package com.bridgeintelligent.tag.engine.mvc.service.impl;

import com.bridgeintelligent.tag.engine.api.BaseCode;
import com.bridgeintelligent.tag.engine.api.CustQueryModel;
import com.bridgeintelligent.tag.engine.api.IndexNameInfo;
import com.bridgeintelligent.tag.engine.api.rsp.CustQuerySetRsp;
import com.bridgeintelligent.tag.engine.core.cache.CacheConfig;
import com.bridgeintelligent.tag.engine.core.cache.CacheUtils;
import com.bridgeintelligent.tag.engine.es.base.ESQueryUtils;
import com.bridgeintelligent.tag.engine.es.model.DataSetModel;
import com.bridgeintelligent.tag.engine.es.query.EsQueryBuilder;
import com.bridgeintelligent.tag.engine.mvc.service.ICustQueryService;
import com.bridgeintelligent.tag.engine.mvc.service.IEsDateService;
import com.bridgeintelligent.tag.utils.FieldHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.Strings;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@AllArgsConstructor
@Service
@Slf4j
public class CustQueryServiceImpl implements ICustQueryService {

    private IEsDateService dateService;

    @Override
    public CustQuerySetRsp custQuery(CustQueryModel queryModel) {
        //封装查询数据
        DataSetModel dataSetModel = new DataSetModel();
        dataSetModel.setFrom(queryModel.getFrom());
        dataSetModel.setSize(queryModel.getSize());
        Map<String, String> relation = dateService.symbolRelation(queryModel.getIndexId());
        //list转set,过滤重复字段
        List<String> fieldsSet = fetchDateField(queryModel.getFields(), queryModel.getDataDate(),relation);
        String[] includes = new String[fieldsSet.size()];
        //设置包含项
        dataSetModel.setIncludes(fieldsSet.toArray(includes));
        //设置排除项，排除项为空
        dataSetModel.setExcludes(Strings.EMPTY_ARRAY);
        //此处判断客群是动静态走不同的查询条件
        if (FieldHandler.FALSE.equals(queryModel.getDateType())){
            dataSetModel.setQueryBuilder(EsQueryBuilder.buildFilter(queryModel.getFilterGroup()));
        }else{
            dataSetModel.setQueryBuilder(QueryBuilders.termsQuery(FieldHandler.CUSTOMER_FLAG,queryModel.getCustomersId()));
        }
        
        IndexNameInfo indexNameInfo = CacheUtils.getCacheInfo(CacheConfig.CONFIGURATION_INFO, queryModel.getIndexId());
        return custQuerycreate(ESQueryUtils.dataSetSearch(indexNameInfo.getDataDate(), dataSetModel), queryModel.getFrom(),queryModel.getSize(), fieldsSet,queryModel.getDataDate());
    }

    private CustQuerySetRsp custQuerycreate(SearchResponse searchResponse, int from, int size, List<String> fieldsSet,String dataDate) {
        CustQuerySetRsp resp = new CustQuerySetRsp();
        SearchHits searchHits = searchResponse.getHits();
        long count = searchHits.getTotalHits().value;
        CustQuerySetRsp.DataRsp dataRsp = new CustQuerySetRsp.DataRsp();
        dataRsp.setTotalElements(count);
        dataRsp.setSize(size);
        dataRsp.setPage(from);
        dataRsp.setTotalPages((int) Math.ceil((double) count / size));
        //根据fieldsSet解析数据并设置content
        dataRsp.setContent(dataHandler(searchHits, fieldsSet ,dataDate));
        resp.setCode(BaseCode.SUCCESS);
        resp.setData(dataRsp);
        return resp;
    }

    private List<Map<String, Object>> dataHandler(SearchHits searchHits, List<String> fieldsSet ,String dataDate) {
        SearchHit[] hits = searchHits.getHits();
        List<Map<String, Object>> result = new ArrayList<>(hits.length);
        Map<String,Object> detailMap = null;
        for (SearchHit searchHit : hits) {
            //得到sourceMap
            Map<String, Object> sourceMap = searchHit.getSourceAsMap();
            detailMap = new HashMap<>();
            for (String field:fieldsSet) {
                detailMap.put(FieldHandler.reduceSuffixField(field,dataDate),sourceMap.get(field));
            }
            result.add(detailMap);
            detailMap = null;
        }
        return result;
    }


    private List<String> fetchDateField(List<String> fieldsSet, String dataDate,Map<String, String> relation ) {
        return fieldsSet.stream()
                        .map(s -> {
                            return FieldHandler.addSuffixField(s,dataDate,relation);
                        })
                        .collect(Collectors.toList());
    }

}
